/*
 * ConfigNouvellePartie.java
 * Classe d'initialisation d'un nouvelle partie
 */
package Risk.IHM;
import Risk.IHM.MenuConnexion.EtapeJeu;

import Risk.Moteur.Jeu;
import Risk.Moteur.Joueur;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.io.File;

import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Configure une nouvelle partie
 * @author Nicoleta Sergi
 */
public class ConfigNouvellePartie extends JFrame implements ActionListener {
    // variables statiques
    private static final long		serialVersionUID = 1L;
    // chemin d'images des cartes
    private static final String		cheminImgPlateau = "Images/PlateauxImg/";
    // noms par defaut des joueurs
    private static final String[]	noms             = {
	"Joueur1", "Joueur2", "Joueur3", "Joueur4", "Joueur5", "Joueur6"
    };
    // tableau par defaut des couleurs des joueurs    
    private static final Color[]	couleurs         = {
	Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.DARK_GRAY, Color.MAGENTA
    };
    // le nom de la carte par defaut utilise
    private static String		choix_carte;
    // variable de classe 
    public static ConfigNouvellePartie	config;
    
    // composantest graphiques
    private ButtonGroup			bgRadioBoutons;
    private String			cheminFich, radicalFich, nomFich;
    private ImageIcon			imgPreview;
    private JButton			jbChoixCarte, jbCancel, jbStart;
    private JRadioButton		jrbConquete, jrbMissSecrete;    
    private JLabel                      previewCarte;

    // jeu virtuel
    private Jeu                         risk;
    // le plateau de jeu 
    private PlateauIhm			plateauIhm;
    
    // vecteurs de composantes graphiques utilises par une fabrique
    private Vector<JCheckBox>           vJChkBx;
    private Vector<JTextField>          vJTxtFld;
    private Vector<JButton>             vJbutton;

    /**
     * constructeur de configuration d'une partie
     */
    public ConfigNouvellePartie() {
	super(" Nouveau jeu ");
	config = this;

	final EtapeJeu	s = MenuConnexion.etape;

	choix_carte = "carte2.png";    // par defaut la carte no 2
        
       	// initialisation vecteurs composantes
	vJChkBx  = new Vector<JCheckBox>();
	vJTxtFld = new Vector<JTextField>();
	vJbutton = new Vector<JButton>();

	// bouttons lancement de partie
	jbCancel = new JButton(" CANCEL ");
	jbCancel.addActionListener(this);
	jbStart = new JButton(" START GAME ");
	jbStart.addActionListener(this);

	// paneau cotenant le bouton pour choisir un plateau ainsi que la variante de jeu
	JPanel	pGauche = initPanelGauche();

	// paneau contenant les joueurs et leurs couleurs
	JPanel	pDroit = initPanelDroit();

	// paneau contenant les boutons de lancement et annulation
	JPanel	jpBas = new JPanel(new GridLayout(1, 2));

	jpBas.add(jbCancel);
	jpBas.add(jbStart);

	// diviseur ecran
	JSplitPane	jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pGauche, pDroit);

	jsp.setDividerLocation(0.5);
	this.setBackground(Color.WHITE);
	this.add(jsp, BorderLayout.CENTER);
	this.add(jpBas, BorderLayout.SOUTH);
	this.pack();
        
        // position de la fenetre
	Dimension	ecran = Toolkit.getDefaultToolkit().getScreenSize();       
        Dimension frameSize = this.getSize();
        this.setLocation((ecran.width - frameSize.width)/2,(ecran.height - frameSize.height)/2);

        
	this.addWindowListener(new WindowAdapter() {
	    @Override
	    public void windowClosing(WindowEvent w) {
		MenuConnexion.menuConnect.setVisible(true);
		MenuConnexion.menuConnect.setEnabled(true);
		MenuConnexion.menuConnect.updateCommandButtons(s.DEBUT);
	    }
	});
	this.setVisible(true);
    }

    /**
     * gestion evenements
     */
    public void actionPerformed(ActionEvent e) {
	Object	o = e.getSource();

	if (o.equals(jbStart)) {
           if (plateauIhm == null) {

		/**
		 * INITIALISE le jeu virtuel (avec test si reussi)
		 * @author Alex
		 */
		if (!initialiseRiskVirtuel()) {
		    System.out.println("Erreur dans actionPerformed : initalisation du jeu virtuel a echoue");

		    return;
		}

		plateauIhm = new PlateauIhm(risk, true);
		risk.setPihm(plateauIhm);
                //si on est en mode connecte
		if (ConnexionServeurIHM.CONNECTE) {
		    risk.setTc(MenuConnexion.menuConnect.getFenetreConnexionServeur().getTc());
		    plateauIhm.getJtaConsole().append(risk.getTc().debutDeJeu() + "\n");
                    //ecriture des messages envoyes vers le serveur dans le jtp
		    for (Joueur j : risk.getJoueurs()) {
			plateauIhm.getJtaConsole().append(risk.getTc().envoieInitialisationJoueur(j) + "\n");
		    }
		}

		MenuConnexion.menuConnect.setDernierPlateau(plateauIhm);
	    }

	    // DEBUG
	    // System.out.println("Chemin "+ cheminFich+ "radical fichier "+radicalFich+"nom fichier "+nomFich);
	    if (cheminFich != null) {
		plateauIhm.remplacerCarte(cheminFich + radicalFich + ".dat", cheminFich + nomFich);
		plateauIhm.majPanneau();
	    }

	    this.setVisible(false);
	}
        /**
         * choix d'une nouvelle carte 
         * @author Nicoleta
         */
	if (o.equals(jbChoixCarte)) {
	    JFileChooser		jfc    = new JFileChooser("."+File.separator+"Images"+File.separator
                    +"PlateauxImg");
	    FileNameExtensionFilter	filter = new FileNameExtensionFilter("Fichiers Images", "jpg", "gif", "png");

	    jfc.setFileFilter(filter);

	    int	returnVal = jfc.showOpenDialog(this);

	    if (returnVal == JFileChooser.APPROVE_OPTION) {
		File	fichier = jfc.getSelectedFile();

		nomFich = fichier.getName();

		StringTokenizer	st = new StringTokenizer(nomFich, ".");

		radicalFich = st.nextToken();
		cheminFich  = fichier.getParent();
		cheminFich  += File.separator;

		// preview de l'image
		imgPreview = new ImageIcon(cheminImgPlateau + nomFich);
		imgPreview.setImage(imgPreview.getImage().getScaledInstance(256, 256, Image.SCALE_DEFAULT));
		previewCarte.setIcon(imgPreview);
		this.pack();
	    }
	}
        /**
         * le bouton cancel nous fait revenir au menu de connexion
         * @author Nicoleta
         */
	if (o.equals(jbCancel)) {
	    this.setVisible(false);
	    MenuConnexion.menuConnect.setVisible(true);
	    MenuConnexion.menuConnect.setEnabled(true);
	}
         /**
         * selection sur les jcheckbox
         * @author Nicoleta
         */
	if (e.getSource() instanceof JCheckBox) {
	    for (int i = 0; i < vJChkBx.size(); i++) {
		if (vJChkBx.get(i).isSelected() == true) {
		    vJTxtFld.get(i).setEnabled(true);
		} else {
		    vJTxtFld.get(i).setEnabled(false);
		}
	    }
	}
    }

    /**
     * fabrique de creation d'une ligne contenant le nom du joueur ainsi que sa couleur
     * @param txt - nom du joueur
     * @param c - couleur du joueur
     * @return - le panel en gridlayout contenant la representation d'un joueur
     */
    private JPanel factoryLigneSelecJoueur(String txt, Color c) {

	// text field avec le nom du joueur
	final JTextField	jtf = new JTextField(txt);

	jtf.setColumns(8);
	jtf.setFocusable(true);
	jtf.addActionListener(this);
	jtf.setEnabled(false);
	jtf.setEditable(true);
        
        //rajoute un focus sur le textfield pour pouvoir selectionner 
        //le nom du joueur en entier lorsqu'on clic dans le textfield
	jtf.addFocusListener(new FocusListener() {
	    public void focusGained(FocusEvent e) {
		if (!jtf.getText().equals("")) {
		    jtf.setSelectionStart(0);
		    jtf.setSelectionEnd(jtf.getText().length());
		}
	    }
	    public void focusLost(FocusEvent e) {
                //le nom du joueur ne doit pas avoir plus de 7 caracteres
                if(jtf.getText().length()>=8){                    
                    String s = jtf.getText();
                    jtf.setText(s.substring(0, 7));
                }
            }
	});

	// case a cocher pour le choix d'un joueur
	JCheckBox	jcb = new JCheckBox();

	jcb.setSelected(false);
	jcb.addActionListener(this);

	/** 
         * bouton avec la couleur d'un joueur
         * le joueur peut changer sa couleur en cliquant sur le bouton
         * @author Alex
         */	
	final JButton	jb1  = new JButton();
	final Component	comp = this;

	jb1.setBackground(c);
	jb1.addActionListener(new ActionListener() {
	    public void actionPerformed(ActionEvent e) {               
                Color c = JColorChooser.showDialog(comp, "Choissisez votre couleur", jb1.getBackground());
                if(c!=null){
                    boolean deja = false;
                
                for(int i=0;i<vJbutton.size();i++){
                    if(vJbutton.get(i)!=jb1&&vJbutton.get(i).getBackground().getRGB()==c.getRGB()){
                        JOptionPane.showMessageDialog(ConfigNouvellePartie.config, "Couleur deja utilisee par un joueur !");
                        deja = true;
                        break;
                    }
                }
                if(!deja)
                    jb1.setBackground(c);
                }
            }
            
                
	});

	// panel contenant la ligne d'un joueur
	JPanel	jp = new JPanel(new GridLayout(1, 2));

	jp.add(jtf);

	JPanel	pDroit = new JPanel(new BorderLayout());

	pDroit.add(jcb, BorderLayout.WEST);
	pDroit.add(jb1, BorderLayout.CENTER);
	jp.add(pDroit);

	// vecteurs de composantes graphiques
	vJTxtFld.add(jtf);
	vJChkBx.add(jcb);
	vJbutton.add(jb1);

	return jp;
    }

    /**
     * initialisation du panel de selection des joueurs
     * @return le panel droit de la frame
     */
    private JPanel initPanelDroit() {
	JPanel	result = new JPanel();

	result.setLayout(new GridLayout(6, 1));

	// parcours du tableau de couleurs
	for (int i = 0; i < couleurs.length; i++) {
	    result.add(factoryLigneSelecJoueur(noms[ i ], couleurs[ i ]));

	    // 2 joueurs sont proposes par defaut
	    if ((i == 0) || (i == 1)) {
		vJChkBx.get(i).setSelected(true);
		vJTxtFld.get(i).setEnabled(true);
	    }
	}

	return result;
    }

    /**
     * initialisaton du paneau de choix des joueurs
     * @return la panel gauche de la frame
     */
    private JPanel initPanelGauche() {
        //panel resultat
	JPanel	result = new JPanel();
	result.setLayout(new BorderLayout());
        //panel haut
	JPanel	haut = new JPanel(new BorderLayout());

	// file chooser pour chercher les cartes
	jbChoixCarte = new JButton("Choisir une carte...");
	jbChoixCarte.addActionListener(this);
	previewCarte = new JLabel();

	// image de la carte configuree par defaut
	imgPreview = new ImageIcon(cheminImgPlateau + choix_carte);
	imgPreview.setImage(imgPreview.getImage().getScaledInstance(256, 256, Image.SCALE_DEFAULT));
	previewCarte.setIcon(imgPreview);
	haut.add(previewCarte, BorderLayout.CENTER);
	haut.add(jbChoixCarte, BorderLayout.SOUTH);

	JPanel	bas         = new JPanel(new GridLayout(3, 1));
	JLabel	jlVariantes = new JLabel("Variante jeu ");

	jrbConquete    = new JRadioButton("Conquerir le monde", true);
	jrbMissSecrete = new JRadioButton("Missions secretes");
	bgRadioBoutons = new ButtonGroup();
	bgRadioBoutons.add(jrbConquete);
	bgRadioBoutons.add(jrbMissSecrete);
	bas.add(jlVariantes);
	bas.add(jrbConquete);
	bas.add(jrbMissSecrete);
	result.add(haut, BorderLayout.CENTER);
	result.add(bas, BorderLayout.SOUTH);

	return result;
    }

    /**
     * lance initialisation du jeu virtuel
     * (Alex)
     * @return true si ok, false sinon
     */
    public boolean initialiseRiskVirtuel() {
	risk = new Jeu();
        String nom_tmp="";
	String	premierJoueur = "";

	// RECUPERE type de partie
	if (jrbConquete.isSelected()) {
	    System.out.println("Mode : Conquerir le monde");
	    risk.setTypePartie(Jeu.CONQUERIR_LE_MONDE);
	} else {
	    System.out.println("Mode : Missions secretes (sans fin)");
	    risk.setTypePartie(Jeu.MISSIONS_SECRETES);
	}

	// RECUPERE les joueurs selectionnes
	for (int i = 0; i < vJChkBx.size(); i++) {
	    if (vJChkBx.get(i).isSelected() == true) {
		if (premierJoueur.equals("")) {
		    premierJoueur = (vJTxtFld.get(i).getText());
		}
                nom_tmp=vJTxtFld.get(i).getText();
                
                if(nom_tmp.length()>7){

                    nom_tmp=nom_tmp.substring(0,7);
                }

		// test si ajout joueurs ok
		if (!risk.ajouteJoueur(nom_tmp, vJbutton.get(i).getBackground())) {
		    System.out.println("Erreur dans initialiseRiskVirtuel : Un joueur ne peut etre ajoute");
		    JOptionPane.showMessageDialog(this, "Erreur : Deux ou plusieurs joueurs ont le meme nom !\n\n"+
                                                "Rappel : le nom d'un joueur doit avoir au maximum 7 caracteres",
						  "Initialisation partie", JOptionPane.ERROR_MESSAGE);

		    return false;
		}

		System.out.println(vJTxtFld.get(i).getText() + " est ajoute a la liste des joueurs en "
				   + vJbutton.get(i).getBackground());
	    }
	}

	int	k = 0;
	for (Joueur j : risk.getJoueurs()) {
	    if (j.getNom().equals(premierJoueur)) {
		risk.setJoueurCourant(k);
	    }

	    k++;
	}

	// TEST si nbJoueurs >= 2
	if (risk.getJoueurs().size() < 2) {
	    System.out.println("Erreur dans initialiseRiskVirtuel : nombre de joueur < 2");
	    JOptionPane.showMessageDialog(this, "Erreur : Le nombre de joueur est infÃ©rieur Ã  2 !",
					  "Initialisation partie", JOptionPane.ERROR_MESSAGE);

	    return false;
	}

	// INITIALISATION de la partie
	risk.initialiseDebutPartie();

	// DEBUG
	// risk.etatPlateau();
	System.out.println("Jeu virtuel ok");

	return true;
    }
    
    /**
     * @return le cheminFich choisit
     */
    public String getCheminFich() {
	return cheminFich;
    }

    /**
     * getter
     * @return le nomFich choisit 
     */
    public String getNomFich() {
	return nomFich;
    }

    /**
     * getter
     * @return le separateur (. ou / ou \)
     */
    public String getRadicalFich() {
	return radicalFich;
    }

    /**
     * setter
     * @param cheminFich - le nouveau cheminFich 
     */
    public void setCheminFich(String cheminFich) {
	this.cheminFich = cheminFich;
    }

    /**
     * setter
     * @param nomFich - le nouveau nomFich
     */
    public void setNomFich(String nomFich) {
	this.nomFich = nomFich;
    }

    /**
     * setter
     * @param radicalFich - le nouveau separateur du chemin
     */
    public void setRadicalFich(String radicalFich) {
	this.radicalFich = radicalFich;
    }

}
